package com.bomberman.environment;

import com.bomberman.environment.Tile;
import com.bomberman.items.Bomb;
import com.bomberman.items.Item;
import com.bomberman.items.PBomb;
import java.util.ArrayList;
import java.awt.Color;

import info.gridworld.actor.*;
import info.gridworld.grid.*;


public class Man extends Actor
//Man, controlled by players, lays bombs, interacts with items, maze, etc.
{
	//Class variables galore, mostly self-explainatory
	private BombWorld w;
	
	private boolean dead = false;
	private Color clr;
	
	private boolean bombLay;
	private int bombs;
	private int power;
	public int bmbMax=7;
	public int pwrMax=7;
	ArrayList<Integer> Bombs = new ArrayList<Integer>();
	
	public int PBombCounter=0;
	
	private String asdwf;//direction code
	
	public Location Loc;
	
	public boolean inTile;
	public int tileTime=0;//unused
	
	private int revCount;
	public int invuln;
	public int deaths=0;

	public Man(String ASDWF, Color Clr, BombWorld world)
	{
		w = world;
		asdwf = ASDWF.substring(0,5);
		clr = Clr;
		dead = false; 
		setColor(clr);
		bombLay = false;
		bombs = 3;
		power = 2;
		revCount = 0;
		inTile = false;
		invuln = 1;
	}
	
	public void act()
	//essentially the timer system. Passive actions (bomb/revive timers)
	{
		if(dead)
		{
			if(revCount<5)
				{revCount++;}
		else if(revCount==5)
				{removeSelfFromGrid(); revive(); revCount=0;}
		return;
		}
		
		if(inTile)
		//Not working / unused
		{
			if(tileTime>3)
			{
				putSelfInGrid(w.getGrid(), w.randLoc());
				dead();
			}
			else
				tileTime++;
			return;
		}
		tileTime=0;
		//
		
		
		if(PBombCounter>0)
			PBombCounter--;
		
			int i=0;
			
			while(i<Bombs.size())
			{
				if(Bombs.get(i)==0)
					{
					Bombs.remove(i);
					bombs++;
					}
				else
					Bombs.set(i, Bombs.get(i++)-1);
			}
		if(getLocation()!=null)
			Loc = getLocation();
		
		if(invuln>0)
			invuln--;
	}
	
	public void layBomb()
	//when Bomb button us pressed ("F"), adds bomb to queue
	{
		if(inTile)
			return;
		if(!bombLay && bombs>0)
		{
		bombLay = true;
		bombs--;
		Bombs.add(3);
		}
	}
	
	public void moveTo(String desc)
	//NOT the inheirited moveTo method, this validates moveTo Loc, and does inTile stuff
	{
		if(dead)
		return;
		
		Grid g = w.getGrid();

		if(inTile)
			{
			Class tileClass = g.get(Loc).getClass();
			
				((Tile) g.get(Loc)).out();
			}
		
		moveTo(asdwLoc(desc, Loc));
	}
	
	public void moveTo(Location toLoc)
	//moves to location, with some Tile/Item checks. Drops bomb if bombLay=true
	{
		Grid g = w.getGrid();
		
		if(!g.isValid(toLoc))
			return;
		
		if(getLocation()==null)
			{
			putSelfInGrid(g, w.randLoc());
			if(g.get(toLoc)== null)
				moveTo(toLoc);
			else
				moveTo(randAdjLoc(Loc));
			}
		
		Location loc = getLocation();
		
		if(g.get(toLoc) == null)
		{
			super.moveTo(toLoc);			
			Loc = toLoc;
		}
		
		if(g.get(toLoc).getClass().getSuperclass().equals(Item.class))
		{
			((Item) g.get(toLoc)).got(this);
			moveTo(toLoc);
			Loc = toLoc;
		}
		
		if(g.get(toLoc).getClass().getSuperclass().equals(Tile.class))
		{
			inTile = ((Tile) g.get(toLoc)).in(this);
			removeSelfFromGrid();
			Loc = toLoc;
		}
		
		if(bombLay)
			if(PBombCounter>0)
			{
			PBomb bomb = new PBomb(power,clr,w);
			w.add(loc, bomb);
			w.Bombs.add(bomb);
			bombLay=false;
			}
			else
			{
			Bomb bomb = new Bomb(power,clr,w);
			w.add(loc, bomb);
			w.Bombs.add(bomb);
			bombLay=false;
			}
	}
	
	public String asdwf(String desc)
	//converts input to ASDW direction
	{
		if(desc.equals(asdwf.substring(0,1)))
			return "A";
		if(desc.equals(asdwf.substring(1,2)))
			return "S";
		if(desc.equals(asdwf.substring(2,3)))
			return "D";
		if(desc.equals(asdwf.substring(3,4)))
			return "W";
		if(desc.equals(asdwf.substring(4,5)))
			return "F";
		
		return null;
	}
	
	public String getASDWF()
	{return asdwf;}
	
	public void dead()
	{if(invuln>0)
		return;
	dead = true;}
	public boolean isDead()
	{return dead;}
	public void revive()
	//after dead, resets values
	// invincible for 2 turns
	{
	deaths++;
	dead = false; 
	setColor(clr);
	bombLay = false;
	bombs = 3;
	Bombs.clear();
	power = 2;
	revCount = 0;
	inTile = false;
	Location loc = w.randLoc();
	w.add(loc, this);
	Loc = loc;
	invuln = 2;
	PBombCounter=0;
	}
	
	public String getImageSuffix()
	{if(dead) return "_dead";
	if(invuln>0) return "_invuln";
	else return "";}
	
	public void removeSelfFromGrid()
	{
		if(getLocation() == null)
			return;
		super.removeSelfFromGrid();
	}
	
	public boolean getBombLay()
	{return bombLay;}
	public void setBombLay(boolean asdf)
	{bombLay = asdf;}
	public int getBombs()
	{return bombs;}
	public void setBombs(int asdf)
	{bombs = asdf;}
	public int getPower()
	{return power;}
	public void setPower(int asdf)
	{power = asdf;}
	public Color getClr()
	{return clr;}
	public void setClr(Color Clr)
	{clr = Clr; setColor(Clr);}
	
	public Location asdwLoc(String asdw, Location Loc)
	//see BombWorld's asdwLoc
   {
		Grid g = w.getGrid();
		
		int x=Loc.getRow(); int y=Loc.getCol();
		
	   		if(asdw.equals("A") && Loc.getCol()>0) 		
	   			y--;
	   else if(asdw.equals("S") && Loc.getRow()<g.getNumRows()) 	
		   		x++;
	   else if(asdw.equals("D") && Loc.getCol()<g.getNumCols()) 	
		   		y++;
	   else if(asdw.equals("W") && Loc.getRow()>0) 		
		   		x--;
	   		
	   		
	   return new Location(x,y);
   }
	
	public Location randAdjLoc(Location Loc)
	//Random Adjacent Location
	{
		String asdw = "ASDW";
		int count = 0;
		while(count < 100000)
		{
			int n = (int)Math.floor(Math.random()*4);
			Location loc = w.asdwLoc(asdw.substring(n,n+1), Loc);
			if(w.getGrid().get(loc)==null)
				return loc;
			count++;
		}
		return w.randLoc();
	}
}